package com.cyzy.controller;

import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch.core.SearchRequest;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.elasticsearch.core.search.Hit;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cyzy.dto.R;
import com.cyzy.esbean.EsQuestions;
import com.cyzy.openfeign.SaveControllerFeign;
import com.cyzy.service.*;
import com.cyzy.vo.*;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.elasticsearch.client.elc.ElasticsearchTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.naming.directory.SearchResult;
import java.io.IOException;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/question")
public class QuestionController {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private SaveControllerFeign saveControllerFeign;

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Autowired
    private QuestionsService questionsService;

    @Autowired
    private ElasticsearchClient elasticsearchClient;

    @Autowired
    private MistakeService mistakeService;

    @Autowired
    private FavoriteService favoriteService;

    @Autowired
    private ExamRecordService examRecordService;

    @Autowired
    private ExamLibraryService examLibraryService;

    @PostMapping("/save")
    public R saveResult(@RequestBody ExamAdmin examAdmin) {
        examAdmin.setCreatetime(new Timestamp(System.currentTimeMillis()));

        // 使用RestTemplate
        //发送http请求给     exam-save微服务    ----->服务间的通信（服务间的调用）
        //第1种： HttpClient【第三方工具】 / RestTemplate【SpringBoot自带】 /改成 OpenFeign
//        String url = "http://localhost:9802/questionsave/save";     //localhost:9802    用微服务名替代
//        String url = "http://exam-save/questionsave/save";
        //第2种： RestTemplate
////        RestTemplate restTemplate = new RestTemplate();   //这里不能new了，使用spring容器中的RestTemplate
//        ResponseEntity<R> responseEntity
//                = restTemplate.postForEntity(url, examAdmin, R.class);
//        System.out.println(responseEntity.getBody()+"----------------23");
//        return responseEntity.getBody();

        //第3种：  使用OpenFeign
//        R r = saveControllerFeign.save(examAdmin);

        rocketMQTemplate.convertAndSend("exam-exercise", examAdmin);
        System.out.println("9811---------------------9811");
        return R.ok();
    }

    @GetMapping("/getQuestionList")
    public R getQuestionList(@RequestParam("userId") int userId,
                             @RequestParam("examLibraryId") int examLibraryId,
                             @RequestParam("currPage") int currPage,
                             @RequestParam("pageSize") int pageSize) {
        return questionsService.getQuestionList(userId,examLibraryId, currPage, pageSize);
    }

    @GetMapping("/getQuestionListByRandom")
    public R getQuestionListByRandom(@RequestParam("userId") int userId,
                                     @RequestParam("examLibraryId") int examLibraryId,
                                     @RequestParam("currPage") int currPage,
                                     @RequestParam("pageSize") int pageSize) {
        return questionsService.getQuestionListByRandom(userId,examLibraryId, currPage, pageSize);
    }

    @GetMapping("/getQuestionListByType")
    public R getQuestionListByType(@RequestParam("userId") int userId,
                                   @RequestParam("examLibraryId") int examLibraryId,
                                   @RequestParam("currPage") int currPage,
                                   @RequestParam("pageSize") int pageSize,
                                   @RequestParam("questionType") int questionType) {
        return questionsService.getQuestionListByType(userId, examLibraryId, questionType, currPage, pageSize);
    }

    @GetMapping("/getQuestionData")
    public R getQuestionData(@RequestParam("examLibraryId") int examLibraryId) {
        return questionsService.getQuestionData(examLibraryId);
    }

    @GetMapping("/getQuestionListByExam")
    public R getQuestionListByExam(@RequestParam("examLibraryId") int examLibraryId) {
        return questionsService.getQuestionListByExam(examLibraryId);
    }

    @GetMapping("/findContent")
    public R findContent(@RequestParam("param") String param, @RequestParam("examLibraryId") long examLibraryId) {
//        try {
//            SearchResponse<EsQuestions> response = elasticsearchClient.search(searchRequest -> searchRequest.index("question_index").query(query -> query.match(field -> field.field("questionText").query(param))), EsQuestions.class);
//            List<Hit<EsQuestions>> hits = response.hits().hits();
//            List<EsQuestions> esQuestions = new ArrayList<>();
//            hits.forEach(item->{
//                esQuestions.add(item.source());
//            });
//            return R.ok().data("data", esQuestions);
//        } catch (IOException e) {
//            throw new RuntimeException(e);
//        }

        try {
            // 构建查询条件：匹配题目内容，并过滤题库ID
            SearchResponse<EsQuestions> response = elasticsearchClient.search(searchRequest -> searchRequest
                            .index("question_index")
                            .size(100)
                            .query(query -> query.bool(boolQuery -> boolQuery
                                    .must(mustQuery -> mustQuery.match(field -> field.field("questionText").query(param)))  // 查询题目内容
                                    .filter(filterQuery -> filterQuery.term(t -> t.field("examLibraryId").value(examLibraryId)))))  // 过滤题库ID
                    , EsQuestions.class);

            // 处理查询结果
            List<Hit<EsQuestions>> hits = response.hits().hits();
            List<EsQuestions> esQuestions = new ArrayList<>();
            hits.forEach(item -> {
                esQuestions.add(item.source());
            });
            // 获取题目数量
            Long totalHits = response.hits().total().value();

            return R.ok().data("questions", esQuestions).data("total", totalHits).code(200);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @PostMapping("/saveMistake")
    public R saveMistake(@RequestBody UserMistakeQuestions userMistakeQuestions) {
        System.out.println("userMistakeQuestions:" + userMistakeQuestions);
        // 查询是否已经存在相同的错题记录
        QueryWrapper<UserMistakeQuestions> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userMistakeQuestions.getUserId())
                .eq("question_id", userMistakeQuestions.getQuestionId());

        // 如果已存在，返回提示
        UserMistakeQuestions existingMistake = mistakeService.getOne(queryWrapper);
        if (existingMistake != null) {
            return R.ok().message("该题目已经存在于错题记录中！");
        }

        userMistakeQuestions.setCreatedAt(new Timestamp(System.currentTimeMillis()));

        // 如果不存在，保存错题记录
        mistakeService.save(userMistakeQuestions);
        return R.ok();
    }

    @GetMapping("/getQuestionListByMistake")
    public R getQuestionListByMistake(@RequestParam("userId") int userId,@RequestParam("examLibraryId") int examLibraryId) {
        return questionsService.getQuestionListByMistake(userId,examLibraryId);
    }

    @PostMapping("/favorite")
    public R favorite(@RequestBody UserFavoriteQuestions userFavoriteQuestions) {
        // 查询收藏表是否已经存在
        QueryWrapper<UserFavoriteQuestions> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userFavoriteQuestions.getUserId())
                .eq("question_id", userFavoriteQuestions.getQuestionId());

        // 如果已存在，返回提示
        UserFavoriteQuestions existingMistake = favoriteService.getOne(queryWrapper);
        if (existingMistake != null) {
            // 如果记录存在，删除该收藏记录
            favoriteService.remove(queryWrapper);
            return R.ok().message("已取消收藏");
        }

        userFavoriteQuestions.setCreatedAt(new Timestamp(System.currentTimeMillis()));

        // 如果不存在，保存错题记录
        favoriteService.save(userFavoriteQuestions);

        return R.ok().message("题目收藏成功");
    }

    @GetMapping("/getQuestionListByFavorite")
    public R getQuestionListByFavorite(@RequestParam("userId") int userId,@RequestParam("examLibraryId") int examLibraryId) {
        return questionsService.getQuestionListByFavorite(userId,examLibraryId);
    }

    @PostMapping("/addExamRecord")
    public R addExamRecord(@RequestBody UserExamRecords userExamRecords) {
        userExamRecords.setCreatedAt(new Timestamp(System.currentTimeMillis()));
        userExamRecords.setUpdatedAt(new Timestamp(System.currentTimeMillis()));
        Time time = Time.valueOf("00:00:00");
        userExamRecords.setDuration(time);  // 设置为 "00:00:00"
        examRecordService.save(userExamRecords);
        return R.ok().code(200);
    }

    @PostMapping("/updateExamRecord")
    public R updateExamRecord(@RequestBody UserExamRecords userExamRecords) {

        // 1. 根据 userId 查询对应的考试记录，按照 id 降序排序，获取最大 id 的记录
        LambdaQueryWrapper<UserExamRecords> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserExamRecords::getUserId, userExamRecords.getUserId())
                .orderByDesc(UserExamRecords::getId)  // 按照 id 降序排序
                .last("LIMIT 1");  // 只获取一条记录，id 最大的

        UserExamRecords existingRecord = examRecordService.getOne(queryWrapper);

        if (existingRecord != null) {
            // 2. 如果记录存在，更新该记录
            existingRecord.setScore(userExamRecords.getScore());
            existingRecord.setDuration(userExamRecords.getDuration());
            existingRecord.setStatus(1);  // 设定状态为已完成
            existingRecord.setUpdatedAt(new Timestamp(System.currentTimeMillis()));

            // 3. 执行更新操作
            boolean updated = examRecordService.updateById(existingRecord);

            if (updated) {
                return R.ok().code(200).message("考试记录已更新");
            } else {
                return R.error().code(500).message("更新失败");
            }
        } else {
            // 4. 如果记录不存在，返回错误信息
            return R.error().code(400).message("找不到对应的考试记录");
        }
    }

    @GetMapping("/getMyScore")
    public R getMyScore(@RequestParam("userId")int userId){
        // 1. 创建查询包装器，按 userId 查询，并按 id 降序排序
        LambdaQueryWrapper<UserExamRecords> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserExamRecords::getUserId, userId)  // 根据 userId 查询
                .orderByDesc(UserExamRecords::getId);  // 按 id 降序排序

        // 2. 查询所有的考试记录
        List<UserExamRecords> examRecords = examRecordService.list(queryWrapper);

        // 如果有考试记录，进行数据处理
        if (examRecords != null && !examRecords.isEmpty()) {
            // 3. 获取所有题库的列表
            List<ExamLibraries> examLibraries = examLibraryService.list();  // 获取所有题库
            // 4. 将题库数据映射到一个 Map 中，key 是 examLibraryId，value 是题库名称
            Map<Long, String> examLibraryMap = examLibraries.stream()
                    .collect(Collectors.toMap(ExamLibraries::getId, ExamLibraries::getName));

            // 5. 遍历考试记录并替换 examLibraryId 为对应的题库名称
            for (UserExamRecords record : examRecords) {
                Long examLibraryId = record.getExamLibraryId();
                if (examLibraryMap.containsKey(examLibraryId)) {
                    // 获取题库名称并设置到 record 中
                    record.setExamLibraryName(examLibraryMap.get(examLibraryId));
                }
            }

            // 6. 返回处理后的考试记录
            return R.ok().code(200).data("examRecords", examRecords);
        } else {
            // 如果没有找到记录，返回错误信息
            return R.error().code(500).message("没有找到对应的考试记录");
        }
    }


}
